//
//  HEChatBar.m
//  HealthElderly
//
//  Created by 吴欧 on 2021/2/9.
//  Copyright © 2021 honglutec. All rights reserved.
//

#import "HEChatBar.h"
#import "HEChatMoreView.h"
#import "HEChatFaceView.h"

#import "HEATPersonListViewController.h"
#import "YYTextAttachmentManager.h"
#import "NSAttributedString+YY.h"

#import "YTRecordStatusView.h"
#import "HEAudioRecordManage.h"
#import "HEIMAudioObject.h"

#import "LCCKInputViewPluginPickImage.h"
#import "HEInputViewPluginConsulReport.h"
#import "HEInputViewPluginVideo.h"
#import "HEInputViewPluginSickbed.h"
#import "HEInputViewPluginDocTeamServer.h"
#import "HEInputViewPluginNotif.h"


#import "HEATPersonListViewController.h"
#import "HEMediaManager.h"
#import "HETimerWeakTarget.h"

@interface HEChatBar ()<UITextViewDelegate, HEAudioRecordManageDelegate>

@property(nonatomic,strong) YTRecordStatusView *recordStatusView;

@property (nonatomic, strong) UIView *inputBarBackgroundView; /**< 输入栏目背景视图 */
@property (strong, nonatomic) UIButton *voiceButton; /**< 切换录音模式按钮 */
@property (strong, nonatomic) UIButton *voiceRecordButton; /**< 录音按钮 */

@property (strong, nonatomic) UIButton *faceButton; /**< 表情按钮 */
@property (strong, nonatomic) UIButton *moreButton; /**< 更多按钮 */

@property (weak, nonatomic) HEChatFaceView *faceView; /**< 当前活跃的底部view,用来指向faceView */
@property (weak, nonatomic) HEChatMoreView *moreView; /**< 当前活跃的底部view,用来指向moreView */

@property (assign, nonatomic, readonly) CGFloat bottomHeight;
@property (strong, nonatomic, readonly) UIViewController *rootViewController;


@property (assign, nonatomic) CGSize keyboardSize;

@property (strong, nonatomic) UITextView *textView;
@property (assign, nonatomic) CGFloat oldTextViewHeight;
@property (nonatomic, assign, getter=shouldAllowTextViewContentOffset) BOOL allowTextViewContentOffset;
@property (nonatomic, assign, getter=isClosed) BOOL close;

@property (nonatomic, assign) BOOL needBack;


#pragma mark - MessageInputView Customize UI
///=============================================================================
/// @name MessageInputView Customize UI
///=============================================================================

@property (nonatomic, strong) UIColor *messageInputViewBackgroundColor;
@property (nonatomic, strong) UIColor *messageInputViewTextFieldTextColor;
@property (nonatomic, strong) UIColor *messageInputViewTextFieldBackgroundColor;
@property (nonatomic, strong) UIColor *messageInputViewRecordTextColor;
//TODO:MessageInputView-Tint-Color

@property (nonatomic, strong) NSMutableSet<NSString *> *mentionSet;

@property (nonatomic, assign) NSInteger bandCount;

@property (nonatomic, strong) NSTimer *bandTimer;


@end

// 广告显示的时间
static int const bandTime = 5;

@implementation HEChatBar


#pragma mark - Life Cycle
- (instancetype)initWithFrame:(CGRect)frame type:(HEIMUserModelType)type{
    if (self = [super initWithFrame:frame]) {
        _type = type;
        self.backgroundColor = UIColor.whiteColor;
        [self setup];
    }
    return self;
}

- (void)setupMorePlugin {
    
    [LCCKInputViewPluginArray removeAllObjects];

    [LCCKInputViewPluginPickImage registerSubclass];
    
    switch (_type) {
        case HEIMUserModelTypeIM:
            [HEInputViewPluginConsulReport registerSubclass];
            break;
        case HEIMUserModelTypeTeamIM:
            [HEInputViewPluginConsulReport registerSubclass];
            [HEInputViewPluginDocTeamServer registerSubclass];
            break;
        case HEIMUserModelTypeSickbed:
            [HEInputViewPluginConsulReport registerSubclass];
            [HEInputViewPluginSickbed registerSubclass];
            break;
        case HEIMUserModelTypeGroup:
            [HEInputViewPluginNotif registerSubclass];
            break;
        default:
            [HEInputViewPluginVideo registerSubclass];
            break;
    }

}

- (void)setupConstraints {
    CGFloat offset = 5;
    [self.inputBarBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.and.right.and.top.mas_equalTo(self);
        make.bottom.mas_equalTo(self).offset(-ZXSafeAreaBottom).priorityLow();
    }];
    
    [self.voiceButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.inputBarBackgroundView.mas_left).with.offset(offset);
        make.bottom.equalTo(self.inputBarBackgroundView.mas_bottom).with.offset(-kChatBarBottomOffset);
        make.width.equalTo(self.voiceButton.mas_height);
    }];
    
    if (_type == HEIMUserModelTypeRoom) {
        [self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.voiceButton.mas_right).with.offset(offset);
            make.right.equalTo(self.inputBarBackgroundView.mas_right).with.offset(-30);
            make.top.equalTo(self.inputBarBackgroundView).with.offset(kChatBarTextViewBottomOffset);
            make.bottom.equalTo(self.inputBarBackgroundView).with.offset(-kChatBarTextViewBottomOffset);
            make.height.mas_greaterThanOrEqualTo(kLCCKChatBarTextViewFrameMinHeight);
        }];
    }else {
        [self.moreButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self.inputBarBackgroundView.mas_right).with.offset(-offset);
            make.bottom.equalTo(self.inputBarBackgroundView.mas_bottom).with.offset(-kChatBarBottomOffset);
            make.width.equalTo(self.moreButton.mas_height);
        }];
        
        [self.faceButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self.moreButton.mas_left).with.offset(-offset);
            make.bottom.equalTo(self.inputBarBackgroundView.mas_bottom).with.offset(-kChatBarBottomOffset);
    //        make.width.equalTo(self.faceButton.mas_height);
            make.width.offset(0);
        }];
        
        
        [self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.voiceButton.mas_right).with.offset(offset);
            make.right.equalTo(self.faceButton.mas_left).with.offset(-offset);
            make.top.equalTo(self.inputBarBackgroundView).with.offset(kChatBarTextViewBottomOffset);
            make.bottom.equalTo(self.inputBarBackgroundView).with.offset(-kChatBarTextViewBottomOffset);
            make.height.mas_greaterThanOrEqualTo(kLCCKChatBarTextViewFrameMinHeight);
        }];
    }
     
    
    CGFloat voiceRecordButtoInsets = -5.f;
    [self.voiceRecordButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(self.textView).insets(UIEdgeInsetsMake(voiceRecordButtoInsets, voiceRecordButtoInsets, voiceRecordButtoInsets, voiceRecordButtoInsets));
    }];
    
    [self.faceView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.and.left.mas_equalTo(self);
        make.height.mas_equalTo(kFunctionViewHeight);
        make.top.mas_equalTo(self.mas_bottom);
    }];
    
    [self.moreView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.and.left.mas_equalTo(self);
        make.height.mas_equalTo(kFunctionViewHeight);
        make.top.mas_equalTo(self.mas_bottom);
    }];
}

- (void)dealloc {
    self.delegate = nil;
    _faceView.delegate = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

#pragma mark -
#pragma mark - Setter Method

- (void)setCachedText:(NSString *)cachedText {
    _cachedText = [cachedText copy];
    if ([_cachedText isEqualToString:@""]) {
        [self updateChatBarConstraintsIfNeededShouldCacheText:NO];
        self.allowTextViewContentOffset = YES;
        return;
    }
    if ([DYTools isBlankString:_cachedText]) {
        _cachedText = @"";
        return;
    }
}

//- (void)setCachedAttrText:(NSAttributedString *)cachedAttrText {
//    _cachedAttrText = [_cachedAttrText copy];
//    if ([_cachedAttrText isEqualToString:@""]) {
//        [self updateChatBarConstraintsIfNeededShouldCacheText:NO];
//        self.allowTextViewContentOffset = YES;
//        return;
//    }
//    if ([DYTools isBlankString:_cachedAttrText]) {
//        _cachedAttrText = @"";
//        return;
//    }
//}

- (UIViewController *)controllerRef {
    return (UIViewController *)self.delegate;
}

- (void)setDelegate:(id<HEChatBarDelegate>)delegate {
    _delegate = delegate;
}

#pragma mark - UITextViewDelegate

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if ([text isEqualToString:@"\n"]) {
        [self sendTextMessage];
        return NO;
    }
    else if ([text isEqualToString:@"@"] && (_type == HEIMUserModelTypeTeamIM || _type == HEIMUserModelTypeRoom || _type == HEIMUserModelTypeGroup)) {
        
        if (range.length > 0) {
            NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text];
//            [self.textView.textStorage replaceCharactersInRange:range withAttributedString:attributedString];
        }
        
        self.needBack = YES; //需要将手动输入的@删除
        
        KWeakSelf
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf presentPersonListViewController];
        });
        return YES;
    }
    return YES;
}

- (void)textViewDidChange:(UITextView *)textView {
    [self textViewDidChange:textView shouldCacheText:YES];
}

- (void)presentPersonListViewController {
    UIViewController *superVC = (UIViewController *)self.delegate;
    
    HEATPersonListViewController *vc = [HEATPersonListViewController new];
    vc.dataSource = self.teamUserList;
    
    KWeakSelf
    [vc vcBackParamBlock:^(HEIMKitInfo *info) {
        [weakSelf addATPerson: info isLong:NO];
    }];
    HEBaseNavigationController *nav= [[HEBaseNavigationController alloc] initWithRootViewController:vc];
    [superVC presentViewController:nav animated:YES completion:nil];
}

- (void)addATPerson:(HEIMKitInfo *)info isLong:(BOOL)isLong{
    
    [self.textView becomeFirstResponder];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
    NSDictionary *attributes = @{NSFontAttributeName:self.textView.font, NSParagraphStyleAttributeName:paragraphStyle};
    //        NSMutableArray *currentSelectedPersonItems = [[self.textView.attributedText getCurrentAtPersonItems] mutableCopy];
    //        [currentSelectedPersonItems addObject:info];//这里可以判断去重...（根据自己需求情况而定）
    
    //将人的名字转化为NSTextAttachment
    KWeakSelf
    [[YYTextAttachmentManager getInstance] transformTextWithTextView:self.textView tickedPersonItems:@[info] atAllPersons:nil canRepeat:YES needBack:self.needBack isLong:isLong color:CNavBgColor attributes:attributes completeBlock:^(NSMutableAttributedString *mutableAttributedString, NSRange selectedRange) {
        weakSelf.needBack = NO;
        weakSelf.textView.selectedRange = selectedRange;
        weakSelf.textView.attributedText = mutableAttributedString;
        weakSelf.cachedAttrText = weakSelf.textView.attributedText;
    }];
}

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
    self.faceButton.selected = self.moreButton.selected = self.voiceButton.selected = NO;
    [self showFaceView:NO];
    [self showMoreView:NO];
    [self showVoiceView:NO];
    return YES;
}

/**
 *  发送普通的文本信息,通知代理
 *
 *  @param text 发送的文本信息
 */
- (void)sendTextMessage {
    NSString *text = self.textView.text.qmui_trim;
    if ([DYTools isBlankString:text]) {
        [Dialog toastBottom:@"不能发送空白消息!"];
        return;
    }
    
    if ([_delegate respondsToSelector:@selector(sendMessage:)]) {
        
        NSDictionary *attcahInfo = [_textView.attributedText getAttachInfo];
        NSArray *ids = attcahInfo[@"ids"];
        
        if (ids.count > 0) {
            
            HEIMATObject *atObject = [HEIMATObject new];
            atObject.atIds = ids;
            
            HEIMMessage *textMessage = [[HEIMMessage alloc] init];
            textMessage.modelType = _type;
            textMessage.type = HEIMMessageTypeAT;
            textMessage.text = attcahInfo[@"text"];
            textMessage.from = _userInfo.id;
            textMessage.to = _session.sessionId;
            textMessage.actor = HEActorTypeUser;
            textMessage.messageObject = atObject;
            
            HEIMMessageModel *model = [[HEIMMessageModel alloc] initWithMessage:textMessage];
            model.deliveryState = HEIMMessageDeliveryStateDelivering;
            
            [_delegate sendMessage: model];
            self.textView.attributedText = nil;

        }else {
            
            HEIMMessage *textMessage = [[HEIMMessage alloc] init];
            textMessage.modelType = _type;
            textMessage.type = HEIMMessageTypeText;
            textMessage.text = text;
            textMessage.from = _userInfo.id;
            textMessage.to =  _session.sessionId;
            textMessage.actor = HEActorTypeUser;
            HEIMMessageModel *model = [[HEIMMessageModel alloc] initWithMessage:textMessage];
            model.deliveryState = HEIMMessageDeliveryStateDelivering;
             
            [_delegate sendMessage: model];
        }
    }
    self.textView.text = nil;
    self.textView.attributedText = nil;
    self.cachedText = @"";
    self.cachedAttrText = nil;
    self.showType = LCCKFunctionViewShowKeyboard;
    
    if (_type == HEIMUserModelTypeRoom) {
        [self bannedSend];
    }
}

#pragma mark - 禁言
- (void)bannedSend {
    _bandCount = bandTime;
    [self.bandTimer fire];
}

- (void)bannedSendAction {
    
    NSInteger cnt = _bandCount--;
    
    [self.textView resignFirstResponder];
    self.textView.editable = NO;
    self.textView.textAlignment = NSTextAlignmentCenter;
    self.textView.userInteractionEnabled = NO;
    self.userInteractionEnabled = NO;

    if (cnt == 0) {
        self.textView.text = nil;
        self.textView.attributedText = nil;
        
        self.textView.editable = YES;
        self.textView.textAlignment = NSTextAlignmentLeft;
        self.textView.userInteractionEnabled = YES;
        self.userInteractionEnabled = YES;
        [_voiceRecordButton setTitle:@"按住 说话" forState:UIControlStateNormal];

        [self stopBandTime];
        return;
    }
    
    self.textView.text = [NSString stringWithFormat:@"%ld秒后可再次发言", cnt];
    [_voiceRecordButton setTitle:[NSString stringWithFormat:@"%ld秒后可再次发言", cnt] forState:UIControlStateNormal];
}


- (void)stopBandTime {
    if (_bandTimer) {
        [_bandTimer invalidate];
        _bandTimer = nil;
    }
}
 
#pragma mark -
#pragma mark - Private Methods

- (void)updateChatBarConstraintsIfNeeded {
    NSString *reason = [NSString stringWithFormat:@"🔴类名与方法名：%@（在第%@行），描述：%@", @(__PRETTY_FUNCTION__), @(__LINE__), @"Should update on main thread"];
    NSAssert([NSThread mainThread], reason);
    BOOL shouldCacheText = NO;
    BOOL shouldScrollToBottom = YES;
    LCCKFunctionViewShowType functionViewShowType = self.showType;
    switch (functionViewShowType) {
        case LCCKFunctionViewShowNothing: {
            shouldScrollToBottom = NO;
            shouldCacheText = YES;
        }
            break;
        case LCCKFunctionViewShowFace:
        case LCCKFunctionViewShowMore:
        case LCCKFunctionViewShowKeyboard: {
            shouldCacheText = YES;
        }
            break;
        case LCCKFunctionViewShowVoice:
            shouldCacheText = NO;
            break;
    }
    [self updateChatBarConstraintsIfNeededShouldCacheText:shouldCacheText];
    [self chatBarFrameDidChangeShouldScrollToBottom:shouldScrollToBottom];
}

- (void)updateChatBarConstraintsIfNeededShouldCacheText:(BOOL)shouldCacheText {
    [self textViewDidChange:self.textView shouldCacheText:shouldCacheText];
}

- (void)updateChatBarKeyBoardConstraints {
    if (self.superview == nil) {
        DLog(@"还没有加入父视图中  ************")
        return;
    }
    [self.inputBarBackgroundView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(self).offset(-0).priorityHigh();
    }];

    [self mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(-self.keyboardSize.height);
    }];
    [UIView animateWithDuration:LCCKAnimateDuration animations:^{
        [self layoutIfNeeded];
    } completion:nil];
}

#pragma mark - 核心方法
///=============================================================================
/// @name 核心方法
///=============================================================================

/*!
 * updateChatBarConstraintsIfNeeded: WhenTextViewHeightDidChanged
 * 只要文本修改了就会调用，特殊情况，也会调用：刚刚进入对话追加草稿、键盘类型切换、添加表情信息
 */
- (void)textViewDidChange:(UITextView *)textView
          shouldCacheText:(BOOL)shouldCacheText {
    if (shouldCacheText) {
//        self.cachedText = self.textView.text;
        self.cachedAttrText = self.textView.attributedText;
    }
    CGRect textViewFrame = self.textView.frame;
    CGSize textSize = [self.textView sizeThatFits:CGSizeMake(CGRectGetWidth(textViewFrame), 1000.0f)];
    // from iOS 7, the content size will be accurate only if the scrolling is enabled.
    textView.scrollEnabled = (textSize.height > kLCCKChatBarTextViewFrameMinHeight);
    // textView 控件的高度在 kLCCKChatBarTextViewFrameMinHeight 和 kLCCKChatBarMaxHeight-offset 之间
    CGFloat newTextViewHeight = MAX(kLCCKChatBarTextViewFrameMinHeight, MIN(kLCCKChatBarTextViewFrameMaxHeight, textSize.height));
    BOOL textViewHeightChanged = (self.oldTextViewHeight != newTextViewHeight);
    if (textViewHeightChanged) {
       //FIXME:如果有草稿，且超出了最低高度，会产生约束警告。
        self.oldTextViewHeight = newTextViewHeight;
        [self.textView mas_updateConstraints:^(MASConstraintMaker *make) {
            CGFloat height = newTextViewHeight;
            make.height.mas_equalTo(height);
        }];
        [self chatBarFrameDidChangeShouldScrollToBottom:YES];
    }
    
    void(^setContentOffBlock)() = ^() {
        if (textView.scrollEnabled && self.allowTextViewContentOffset) {
            if (newTextViewHeight == kLCCKChatBarTextViewFrameMaxHeight) {
                [textView setContentOffset:CGPointMake(0, textView.contentSize.height - newTextViewHeight) animated:YES];
            } else {
                [textView setContentOffset:CGPointZero animated:YES];
            }
        }
    };
    
    //FIXME:issue #178
    //在输入换行的时候，textView的内容向上偏移，再下次输入后恢复正常，原因是高度变化后，textView更新约束，重新设置了contentOffset；我是在设置contentOffset做了0.01秒的延迟，发现能解决这个问题
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        setContentOffBlock();
    });
}

#pragma mark - HEAudioRecordManageDelegate
- (void)audioRecordFinishedWithFilePath:(NSString *)filePath time:(NSInteger)time {
    if (time < 1) {
        [Dialog toastBottom:@"说话时间太短!"];
        // 删除缓存语音文件
        [[HEAudioRecordManage sharedManager] removeFileAtPath:filePath];
        return;
    }
    
    if ([_delegate respondsToSelector:@selector(sendMessage:)]) {
        
        HEIMAudioObject *audio = [HEIMAudioObject new];
        audio.url = filePath;
        audio.duration = time;
         
        HEIMMessage *textMessage = [[HEIMMessage alloc] init];
        textMessage.modelType = _type;
        textMessage.type = HEIMMessageTypeAudio;
        textMessage.from = _userInfo.id;
        textMessage.to =  _session.sessionId;
        textMessage.actor = HEActorTypeUser;
        textMessage.messageObject = audio;
        
        HEIMMessageModel *model = [[HEIMMessageModel alloc] initWithMessage:textMessage];
        model.deliveryState = HEIMMessageDeliveryStateDelivering;
         
        [_delegate sendMessage: model];
    }
    
    if (_type == HEIMUserModelTypeRoom) {
        [self bannedSend];
    }
}

/**
 *  通知代理发送图片信息
 *
 *  @param image 发送的图片
 */
- (void)sendImageMessage:(UIImage *)image {
    
}

#pragma mark - LCCKChatFaceViewDelegate

- (void)faceViewSendFace:(NSString *)faceName {
}

#pragma mark - Public Methods

- (void)close {
    //关闭
    self.close = YES;
}

- (void)open {
    self.close = NO;
}

- (void)endInputing {
    if (self.voiceButton.selected) {
        return;
    }
    self.faceButton.selected = self.moreButton.selected = self.voiceButton.selected = NO;
    [self hideMoreView];
    self.showType = LCCKFunctionViewShowNothing;
}

- (void)appendString:(NSString *)string beginInputing:(BOOL)beginInputing {
    self.allowTextViewContentOffset = YES;
    if (self.textView.text.length > 0 && [string hasPrefix:@"@"] && ![self.textView.text hasSuffix:@" "]) {
        self.textView.text = [self.textView.text stringByAppendingString:@" "];
    }
    NSString *textViewText;
    //特殊情况：处于语音按钮显示时，self.textView.text无信息，但self.cachedText有信息
    if (self.textView.text.length == 0 && self.cachedText.length > 0) {
        textViewText = self.cachedText;
    } else {
        textViewText = self.textView.text;
    }
    NSString *appendedString = [textViewText stringByAppendingString:string];
    self.cachedText = appendedString;
    self.textView.text = appendedString;
    if (beginInputing && self.keyboardSize.height == 0) {
        [self beginInputing];
    } else {
        [self updateChatBarConstraintsIfNeeded];
    }
}

- (void)appendString:(NSString *)string {
    [self appendString:string beginInputing:YES];
}

- (void)appendString:(NSString *)string mentionList:(NSArray<NSString *> *)mentionList
{
    [self.mentionSet addObjectsFromArray:mentionList];
    [self appendString:string beginInputing:YES];
}

- (void)beginInputing {
    [self.textView becomeFirstResponder];
}

#pragma mark - Private Methods

- (void)keyboardWillHide:(NSNotification *)notification {
    NSString *reason = [NSString stringWithFormat:@"🔴类名与方法名：%@（在第%@行），描述：%@", @(__PRETTY_FUNCTION__), @(__LINE__), @"Should update on main thread"];
    NSAssert([NSThread mainThread], reason);
    if (self.isClosed) {
        return;
    }
    self.keyboardSize = CGSizeZero;

    if (_showType == LCCKFunctionViewShowKeyboard) {
        _showType = LCCKFunctionViewShowNothing;
    }
    
    if (_showType == LCCKFunctionViewShowNothing ||
        _showType == LCCKFunctionViewShowVoice){
        [self hideMoreView];
    }
    [self updateChatBarKeyBoardConstraints];
    [self updateChatBarConstraintsIfNeeded];
}

- (void)hideMoreView {
    // 这里将依赖inputBarBackgroundView，顶起inputBarBackgroundView
    [self.moreView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.inputBarBackgroundView.mas_bottom);
    }];
    // 在这里改变charBar底部的高度
    [UIView animateWithDuration:LCCKAnimateDuration animations:^{
        CGFloat bh = self.keyboardSize.height;
        if (bh == 0) {
            bh = ZXSafeAreaBottom;
        }
        [self.moreView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.superview.mas_bottom).offset(-bh);
        }];
        [self.moreView layoutIfNeeded];
        self.moreView.alpha = 0;
    } completion:^(BOOL finished) {
        self.moreView.hidden = YES;
    }];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    NSString *reason = [NSString stringWithFormat:@"🔴类名与方法名：%@（在第%@行），描述：%@", @(__PRETTY_FUNCTION__), @(__LINE__), @"Should update on main thread"];
    NSAssert([NSThread mainThread], reason);
    if (self.isClosed) {
        return;
    }
    CGFloat oldHeight = self.keyboardSize.height;
    self.keyboardSize = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    //兼容搜狗输入法：一次键盘事件会通知两次，且键盘高度不一。
    if (self.keyboardSize.height != oldHeight) {
        _showType = LCCKFunctionViewShowNothing;
    }
    if (self.keyboardSize.height == 0) {
        _showType = LCCKFunctionViewShowNothing;
        return;
    }
    self.allowTextViewContentOffset = YES;
    
    // 在这里改变charBar底部的高度
    [UIView animateWithDuration:LCCKAnimateDuration animations:^{
        [self.moreView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.superview.mas_bottom).offset(-self.keyboardSize.height);
        }];
        [self.moreView layoutIfNeeded];
    } completion:nil];
    
    [self updateChatBarKeyBoardConstraints];
    self.showType = LCCKFunctionViewShowKeyboard;
}

/**
 *  lazy load inputBarBackgroundView
 *
 *  @return UIView
 */
- (UIView *)inputBarBackgroundView {
    if (_inputBarBackgroundView == nil) {
        UIView *inputBarBackgroundView = [[UIView alloc] init];
        _inputBarBackgroundView = inputBarBackgroundView;
        _inputBarBackgroundView.backgroundColor = UIColor.whiteColor;
    }
    return _inputBarBackgroundView;
}

- (void)setup {

    // 录音
    self.recordStatusView = [YTRecordStatusView Instance];
    [HEAudioRecordManage sharedManager].delegate = self;
    
    // 设置更多面板插件
    [self setupMorePlugin];
    _userInfo = [[UserManager sharedUserManager] getUserInfo];

    self.close = NO;
    self.oldTextViewHeight = kLCCKChatBarTextViewFrameMinHeight;
    self.allowTextViewContentOffset = YES;

    [self faceView];
    [self moreView];
    [self addSubview:self.inputBarBackgroundView];
    
    [self.inputBarBackgroundView addSubview:self.voiceButton];
    [self.inputBarBackgroundView addSubview:self.moreButton];
    [self.inputBarBackgroundView addSubview:self.faceButton];
    [self.inputBarBackgroundView addSubview:self.textView];
    [self.inputBarBackgroundView addSubview:self.voiceRecordButton];
    
    if (_type == HEIMUserModelTypeRoom) { // 圈子聊天 仅语音和文字
        [self.moreButton removeFromSuperview];
        [self.faceButton removeFromSuperview];
    }
    
    UIImageView *topLine = [[UIImageView alloc] init];
    topLine.backgroundColor = kLCCKTopLineBackgroundColor;
    [self.inputBarBackgroundView addSubview:topLine];
    [topLine mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.and.right.and.top.equalTo(self.inputBarBackgroundView);
        make.height.mas_equalTo(.5f);
    }];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    self.backgroundColor = self.messageInputViewBackgroundColor;
    [self setupConstraints];
    
    self.mentionSet = [NSMutableSet set];
}

/**
 *  开始录音
 */
- (void)startRecordVoice {
    
    [[HEMediaManager sharedManager] stopPlay];

    self.voiceRecordButton.highlighted = YES;
    [_voiceRecordButton setTitle:@"松开 结束" forState:UIControlStateNormal];

    [_recordStatusView dismiss];
    [_recordStatusView showInWindow];
    
    [[HEAudioRecordManage sharedManager] startRecord];
    
    [[HEAudioRecordManage sharedManager] updatePower:^(CGFloat power) {
        [self.recordStatusView updateWithPower:power];
    }];
}

/**
 *  取消录音
 */
- (void)cancelRecordVoice {
    self.voiceRecordButton.highlighted = NO;
    [_voiceRecordButton setTitle:@"按住 说话" forState:UIControlStateNormal];

    _recordStatusView.voiceActionMode = VoiceMode_ReleaseToCancel;
    [_recordStatusView dismiss];
    [[HEAudioRecordManage sharedManager] cancelRecord];
}

/**
 *  录音结束
 */
- (void)confirmRecordVoice {
    self.voiceRecordButton.highlighted = NO;
    [_voiceRecordButton setTitle:@"按住 说话" forState:UIControlStateNormal];

    [_recordStatusView dismiss];
    [[HEAudioRecordManage sharedManager] endRecord];
}

/**
 *  更新录音显示状态,手指向上滑动后提示松开取消录音
 */
- (void)updateCancelRecordVoice {
    _recordStatusView.voiceActionMode = VoiceMode_ReleaseToCancel;
}

/**
 *  更新录音状态,手指重新滑动到范围内,提示向上取消录音
 */
- (void)updateContinueRecordVoice {
    _recordStatusView.voiceActionMode = VoiceMode_ReleaseToSend;
}

- (void)setShowType:(LCCKFunctionViewShowType)showType {
    if (_showType == showType) {
        return;
    }
    _showType = showType;
    //显示对应的View
    [self showMoreView:showType == LCCKFunctionViewShowMore && self.moreButton.selected];
    [self showVoiceView:showType == LCCKFunctionViewShowVoice && self.voiceButton.selected];
    [self showFaceView:showType == LCCKFunctionViewShowFace && self.faceButton.selected];
    
    switch (showType) {
        case LCCKFunctionViewShowNothing: {
//            self.textView.text = self.cachedText;
            self.textView.attributedText = self.cachedAttrText;
            [self.textView resignFirstResponder];
        }
            break;
        case LCCKFunctionViewShowVoice: {
//            self.cachedText = self.textView.text;
            self.cachedAttrText = self.textView.attributedText;

            self.textView.text = nil;
            [self.textView resignFirstResponder];
        }
            break;
        case LCCKFunctionViewShowMore:
        case LCCKFunctionViewShowFace:
//            self.textView.text = self.cachedText;
            self.textView.attributedText = self.cachedAttrText;

            [self.textView resignFirstResponder];
            break;
        case LCCKFunctionViewShowKeyboard:
//            self.textView.text = self.cachedText;
            self.textView.attributedText = self.cachedAttrText;

            break;
    }
    [self updateChatBarConstraintsIfNeeded];
}

- (void)hidekeyBoard {
    [self.textView resignFirstResponder];
}

- (void)buttonAction:(UIButton *)button {
    LCCKFunctionViewShowType showType = button.tag;
    //更改对应按钮的状态
    if (button == self.faceButton) {
        [self.faceButton setSelected:!self.faceButton.selected];
        [self.moreButton setSelected:NO];
        [self.voiceButton setSelected:NO];
    } else if (button == self.moreButton){
        [self.faceButton setSelected:NO];
        [self.moreButton setSelected:!self.moreButton.selected];
        [self.voiceButton setSelected:NO];
    } else if (button == self.voiceButton){
        [self.faceButton setSelected:NO];
        [self.moreButton setSelected:NO];
        [self.voiceButton setSelected:!self.voiceButton.selected];
        [self hideMoreView];
    }
    if (!button.selected) {
        showType = LCCKFunctionViewShowKeyboard;
        [self beginInputing];
    }
    self.showType = showType;
}

- (void)showFaceView:(BOOL)show {
    if (show) {
        self.faceView.hidden = NO;
        [UIView animateWithDuration:LCCKAnimateDuration animations:^{
            [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.top.mas_equalTo(self.superview.mas_bottom).offset(-kFunctionViewHeight);
            }];
            [self.faceView layoutIfNeeded];
        } completion:nil];
        
        [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.inputBarBackgroundView.mas_bottom);
        }];
    } else if (self.faceView.superview) {
        self.faceView.hidden = YES;
        [self.faceView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.width.and.left.mas_equalTo(self);
            make.height.mas_equalTo(kFunctionViewHeight);
            make.top.mas_equalTo(self.mas_bottom);
        }];
        [self.faceView layoutIfNeeded];
    }
}

/**
 *  显示moreView
 *  @param show 要显示的moreView
 */
- (void)showMoreView:(BOOL)show {
    
    if (show) {
        self.moreView.hidden = NO;
        [UIView animateWithDuration:LCCKAnimateDuration animations:^{
            self.moreView.alpha = 1;
            [self.moreView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.top.mas_equalTo(self.superview.mas_bottom).offset(-kFunctionViewHeight);
            }];
            [self.moreView layoutIfNeeded];
        } completion:nil];

        [self.moreView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.inputBarBackgroundView.mas_bottom);
        }];
    } else if (self.moreView.superview) {
        // 不能这么写，会导致底部先为0 在为键盘高度，体验不好
//        self.moreView.hidden = YES;
//        [self.moreView mas_remakeConstraints:^(MASConstraintMaker *make) {
//            make.width.and.left.mas_equalTo(self);
//            make.height.mas_equalTo(kFunctionViewHeight);
//            make.top.mas_equalTo(self.mas_bottom);
//        }];
//        [self.moreView layoutIfNeeded];
    }
}

- (void)showVoiceView:(BOOL)show {
    self.voiceButton.selected = show;
    self.voiceRecordButton.selected = show;
    self.voiceRecordButton.hidden = !show;
    self.textView.hidden = !self.voiceRecordButton.hidden;
}

/**
 *  发送普通的文本信息,通知代理
 *
 *  @param text 发送的文本信息
 */
- (void)sendTextMessage:(NSString *)text{
//    if (!text || text.length == 0 || [text lcck_isSpace]) {
//        return;
//    }
//    NSArray<NSString *> *mentionList = self.mentionSet.allObjects;
//    [self.mentionSet removeAllObjects];
//    if (self.delegate && [self.delegate respondsToSelector:@selector(chatBar:sendMessage:mentionList:)]) {
//        [self.delegate chatBar:self sendMessage:text mentionList:mentionList];
//    }
    self.textView.text = @"";
    self.cachedText = @"";
    self.cachedAttrText = @"";
    self.showType = LCCKFunctionViewShowKeyboard;
}

- (void)chatBarFrameDidChangeShouldScrollToBottom:(BOOL)shouldScrollToBottom {
    NSString *reason = [NSString stringWithFormat:@"🔴类名与方法名：%@（在第%@行），描述：%@", @(__PRETTY_FUNCTION__), @(__LINE__), @"Should update on main thread"];
    NSAssert([NSThread mainThread], reason);
    if (self.delegate && [self.delegate respondsToSelector:@selector(chatBarFrameDidChange:shouldScrollToBottom:)]) {
        [self.delegate chatBarFrameDidChange:self shouldScrollToBottom:shouldScrollToBottom];
    }
}

- (UIImage *)imageInBundlePathForImageName:(NSString *)imageName {
    UIImage *image = [UIImage wo_imageNamed:imageName bundleName:@"ChatKeyboard" bundleForClass:[self class]];
    return image;
}

#pragma mark - Getters

- (HEChatFaceView *)faceView {
    if (!_faceView) {
        HEChatFaceView *faceView = [[HEChatFaceView alloc] init];
        faceView.delegate = self;
        faceView.hidden = YES;
        faceView.backgroundColor = self.backgroundColor;
        [self addSubview:(_faceView = faceView)];
    }
    return _faceView;
}

- (HEChatMoreView *)moreView {
    if (!_moreView) {
        HEChatMoreView *moreView = [[HEChatMoreView alloc] init];
        moreView.inputViewRef = self;
        moreView.hidden = YES;
        [self addSubview:(_moreView = moreView)];
    }
    return _moreView;
}

- (UITextView *)textView {
    if (!_textView) {
        _textView = [[UITextView alloc] init];
        _textView.font = [UIFont systemFontOfSize:16.0f];
        _textView.delegate = self;
        _textView.layer.cornerRadius = 4.0f;
        _textView.textColor = self.messageInputViewTextFieldTextColor;
        _textView.backgroundColor = self.messageInputViewTextFieldBackgroundColor;
        _textView.layer.borderColor = [UIColor colorWithRed:204.0/255.0f green:204.0/255.0f blue:204.0/255.0f alpha:1.0f].CGColor;
        _textView.returnKeyType = UIReturnKeySend;
        _textView.layer.borderWidth = .5f;
        _textView.layer.masksToBounds = YES;
        _textView.scrollsToTop = NO;
    }
    return _textView;
}

- (UIButton *)voiceButton {
    if (!_voiceButton) {
        _voiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _voiceButton.tag = LCCKFunctionViewShowVoice;
        [_voiceButton setTitleColor:self.messageInputViewRecordTextColor forState:UIControlStateNormal];
        [_voiceButton setTitleColor:self.messageInputViewRecordTextColor forState:UIControlStateHighlighted];
        [_voiceButton setBackgroundImage:[self imageInBundlePathForImageName:@"ToolViewInputVoice"] forState:UIControlStateNormal];
        [_voiceButton setBackgroundImage:[self imageInBundlePathForImageName:@"ToolViewKeyboard"] forState:UIControlStateSelected];
        [_voiceButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_voiceButton sizeToFit];
    }
    return _voiceButton;
}

- (UIButton *)voiceRecordButton {
    if (!_voiceRecordButton) {
        _voiceRecordButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _voiceRecordButton.hidden = YES;
        _voiceRecordButton.frame = self.textView.bounds;
        _voiceRecordButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [_voiceRecordButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
        UIEdgeInsets edgeInsets = UIEdgeInsetsMake(9, 9, 9, 9);
        UIImage *voiceRecordButtonNormalBackgroundImage = [[self imageInBundlePathForImageName:@"VoiceBtn_Black"] resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];
        UIImage *voiceRecordButtonHighlightedBackgroundImage = [[self imageInBundlePathForImageName:@"VoiceBtn_BlackHL"] resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];
        [_voiceRecordButton setBackgroundImage:voiceRecordButtonNormalBackgroundImage forState:UIControlStateNormal];
        [_voiceRecordButton setBackgroundImage:voiceRecordButtonHighlightedBackgroundImage forState:UIControlStateHighlighted];
        _voiceRecordButton.titleLabel.font = [UIFont systemFontOfSize:14.0f];
        [_voiceRecordButton setTitle:@"按住 说话" forState:UIControlStateNormal];
        [_voiceRecordButton setTitle:@"松开 结束" forState:UIControlStateHighlighted];
        [_voiceRecordButton addTarget:self action:@selector(startRecordVoice) forControlEvents:UIControlEventTouchDown];
        [_voiceRecordButton addTarget:self action:@selector(cancelRecordVoice) forControlEvents:UIControlEventTouchUpOutside];
        [_voiceRecordButton addTarget:self action:@selector(confirmRecordVoice) forControlEvents:UIControlEventTouchUpInside];
        [_voiceRecordButton addTarget:self action:@selector(updateCancelRecordVoice) forControlEvents:UIControlEventTouchDragExit];
        [_voiceRecordButton addTarget:self action:@selector(updateContinueRecordVoice) forControlEvents:UIControlEventTouchDragEnter];
    }
    return _voiceRecordButton;
}

- (UIButton *)moreButton {
    if (!_moreButton) {
        _moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _moreButton.tag = LCCKFunctionViewShowMore;
        [_moreButton setBackgroundImage:[self imageInBundlePathForImageName:@"TypeSelectorBtn_Black"] forState:UIControlStateNormal];
        [_moreButton setBackgroundImage:[self imageInBundlePathForImageName:@"TypeSelectorBtn_Black"] forState:UIControlStateSelected];
        [_moreButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_moreButton sizeToFit];
    }
    return _moreButton;
}

- (UIButton *)faceButton {
    if (!_faceButton) {
        _faceButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _faceButton.tag = LCCKFunctionViewShowFace;
        [_faceButton setBackgroundImage:[self imageInBundlePathForImageName:@"ToolViewEmotion"] forState:UIControlStateNormal];
        [_faceButton setBackgroundImage:[self imageInBundlePathForImageName:@"ToolViewKeyboard"] forState:UIControlStateSelected];
        [_faceButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_faceButton sizeToFit];
    }
    return _faceButton;
}

- (CGFloat)bottomHeight {
    if (self.faceView.superview || self.moreView.superview) {
        return MAX(self.keyboardSize.height, MAX(self.faceView.frame.size.height, self.moreView.frame.size.height));
    } else {
        return MAX(self.keyboardSize.height, CGFLOAT_MIN);
    }
}

- (NSTimer *)bandTimer {
    if (!_bandTimer) {
        _bandTimer = [HETimerWeakTarget scheduledTimerWithTimeInterval:1 target:self selector:@selector(bannedSendAction) userInfo:nil repeats:YES];
    }
    return _bandTimer;
}

- (UIViewController *)rootViewController {
    return [[UIApplication sharedApplication] keyWindow].rootViewController;
}

#pragma mark -
#pragma mark - MessageInputView Customize UI Method

//- (UIColor *)messageInputViewBackgroundColor {
//    if (_messageInputViewBackgroundColor) {
//        return _messageInputViewBackgroundColor;
//    }
//    _messageInputViewBackgroundColor = [[LCCKSettingService sharedInstance] defaultThemeColorForKey:@"MessageInputView-BackgroundColor"];
//    return _messageInputViewBackgroundColor;
//}
//
//- (UIColor *)messageInputViewTextFieldTextColor {
//    if (_messageInputViewTextFieldTextColor) {
//        return _messageInputViewTextFieldTextColor;
//    }
//    _messageInputViewTextFieldTextColor = [[LCCKSettingService sharedInstance] defaultThemeColorForKey:@"MessageInputView-TextField-TextColor"];
//    return _messageInputViewTextFieldTextColor;
//}
//
//- (UIColor *)messageInputViewTextFieldBackgroundColor {
//    if (_messageInputViewTextFieldBackgroundColor) {
//        return _messageInputViewTextFieldBackgroundColor;
//    }
//    _messageInputViewTextFieldBackgroundColor = [[LCCKSettingService sharedInstance] defaultThemeColorForKey:@"MessageInputView-TextField-BackgroundColor"];
//    return _messageInputViewTextFieldBackgroundColor;
//}
//
//- (UIColor *)messageInputViewRecordTextColor {
//    if (_messageInputViewRecordTextColor) {
//        return _messageInputViewRecordTextColor;
//    }
//    _messageInputViewRecordTextColor = [[LCCKSettingService sharedInstance] defaultThemeColorForKey:@"MessageInputView-Record-TextColor"];
//    return _messageInputViewRecordTextColor;
//}


@end
